home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
graphics
/
fpoly256.zip
/
FX3DKIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-27
|
14KB
|
593 lines
#include <bios.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
unsigned int dpaddr = 0; /* video write base */
unsigned long l_hold, r_hold; /* used to hold old x data for edge */
int l_clip = 0; /* clipping rectangle for polys and lines */
int r_clip = 319; /* max. 0,319,0,199 */
int t_clip = 0;
int b_clip = 199;
typedef struct lp { /* set of points for clipping or line dwg */
int x1, y1, x2, y2;
} lpoints;
extern void far vsync(); /* pause till vert. retrace */
extern void far vga_reg(int reg); /* load VGA register: */
/* reg = reg# + 256*value */
extern void far load_color(int color); /* load VGA color register */
extern void far set_vmode(int mode); /* set video mode thru BIOS */
extern void far set_vpage(int page); /* set video page thru BIOS */
#define PUT 0 /* defines of VGA write modes */
#define AND 1 /* for use with setup_hdwe() */
#define OR 2
#define XOR 3
extern void far setup_hdwe(int mode); /* setup VGA for bunch of line */
/* or poly draws: once per set */
extern void far reset_hdwe(); /* reset VGA to BIOS state after drawing */
/* clear video page to solid color: 10 mS */
/* returns -1 if bad page # */
extern int far clr_page(int page, int color);
/* copy one page to another for use as */
/* background: 21 mS per call */
/* returns -1 if bad page # */
extern int far copy_page(int source, int dest);
/* fast VGA line draw: about 15600 24-pixel */
/* vectors/sec (horizontal much faster) */
extern void far vgaline(int x1, int y1, int x2, int y2, int color);
/* line draw using lpoint structure */
void vgalines(lpoints *points, int color);
/* Fast Cohen-Sutherland line clipper */
/* modifies data in points, returns */
/* 0 if not clipped, 1 if clipped, */
/* -1 if undrawable */
/* 2 - 10 uS per call */
int clipper (lpoints far *points);
/* does C-S clipping and draws line */
/* returns same codes as C-S clipper */
int clipline (lpoints *points, int color);
#define NO_HOLD 0 /* values for hold in tpoly() */
#define L_HOLD 1
#define R_HOLD 2
#define HOLD_ALL 3
#define HOLD 0x8000 /* use in x1 or x2 to continue poly side */
/* draws trapeziodal poly slice FAST */
/* x1 is top left, x2 is top right, */
/* y1 is top, y3 is bottom. Clipping */
/* is performed. l_incr and r_incr */
/* set slope of sides. */
/* if x1 or x2 = HOLD, continues that */
/* side from last tpoly call. Use */
/* bits in hold to ensure that needed */
/* side data is good in previous tpoly */
extern int far tpoly(int x1,int x2, long l_incr, long r_incr,
int y1, int y3, int hold);
/* compute (x1-x2)/(y1-y2) << 16 */
/* used for tpoly... */
/* returns x1-x2 if y1==y2 */
extern long far compute_slope(int x1, int x2, int y1, int y2);
void set_gmode(); /* enters 320x200x16 mode, clears screen */
void restore_gmode(); /* enters 320x200x16 mode w/o clearing screen */
void exit_gmode(); /* exits to text mode */
int set_drawpage(int page); /* set page for drawing on (0-7) */
/* set displayed page: uses BIOS */
/* call, so DON'T use in interrupt */
/* routines! If WAIT is 1, will */
/* sync with vert. retrace (pause) */
int set_vidpage(int page, int wait);
/* draw and fill 3-sided polygon */
/* automatically clipped to bounds */
/* not a "pretty poly" fill, so */
/* sliver polys break up. */
/* 5800 polys/sec for 24x24 */
poly3(int x1, int y1, int x2, int y2, int x3, int y3, int color);
/* fastest triangle poly blitter */
/* points must be in CCW order */
/* (clockwise before Y mirror) */
/* and color must have been set */
/* with load_color() before call */
/* NO CLIPPING AT ALL */
void fastri(int x1, int y1, int x2, int y2, int x3, int y3);
/* N_SIDED POLY DRAW DONE WITH TRIANGLES */
/* pass pointers to X, Y coord arrays */
/* and count. No clipping, preset color */
/* with load_color() */
void polynt(int *xcoords, int *ycoords, int count);
/* draw and fill 3-sided polygon */
/* automatically clipped to bounds */
/* not a "pretty poly" fill, so */
/* sliver polys break up. */
/* will draw some concave polys OK */
/* but can't be depended on esp. */
/* if concavity is at top or bot. */
/* 3800 30x30 polys/sec */
poly4(int x1, int y1, int x2, int y2, int x3, int y3,
int x4, int y4, int color);
/************* GRAPHICS MODE CONTROL SUPPORT **************/
void set_gmode() /* enters 320x200x256 mode, clears screen */
{
set_vmode(0x14);
}
void restore_gmode() /* enters 320x200x256 mode w/o clearing screen */
{
set_vmode(0x94);
}
void exit_gmode() /* exits to text mode */
{
set_vmode(0x02);
}
int set_drawpage(int page) /* set page for drawing */
{
if(page>3) return(-1);
dpaddr = 16000*page;
return(0);
}
int set_vidpage(int page, int wait) /* set visible page, wait for vsync */
{
if(page>3) return(-1);
set_vpage(page);
if(wait) vsync();
}
/******************* LINE DRAWING SUPPORT ***************/
void vgalines(lpoints *l, int color)
{
vgaline(l->x1, l->y1, l->x2, l->y2, color);
}
int clipline(lpoints *l, int color)
{
register int i;
if ((i=clipper(l))==-1) return(i);
vgaline(l->x1, l->y1, l->x2, l->y2, color);
return(i);
}
/*************** 3-SIDED POLYGON DRAW AND FILL ***************/
poly3(int x1, int y1, int x2, int y2, int x3, int y3, int color)
{
register int i;
long s12, s23, s13;
/* find if all outside of window */
/* sort of braindead partial clipping */
/* but it's fast and optimal for */
/* small polys */
i = r_clip;
if(!( x1<=i || x2<=i || x3<=i )) return(0);
i = l_clip;
if(!( x1>=i || x2>=i || x3>=i )) return(0);
i = b_clip;
if(!( y1<=i || y2<=i || y3<=i )) return(0);
i = t_clip;
if(!( y1>=i || y2>=i || y3>=i )) return(0);
if(y2<y1) /* sort by vert pos'n */
{
i = y1;
y1 = y2;
y2 = i;
i = x1;
x1 = x2;
x2 = i;
}
if(y3<y1)
{
i = y1;
y1 = y3;
y3 = i;
i = x1;
x1 = x3;
x3 = i;
}
if(y3<y2)
{
i = y2;
y2 = y3;
y3 = i;
i = x2;
x2 = x3;
x3 = i;
}
if(y3<t_clip || y1>b_clip)return(0); /* all above or below clip area */
if(y1==y2&&y2==y3) return;
load_color(color);
if(y1==y2) /* case = 2 (flat top) */
{
if(x2<x1)
{
i = x1;
x1 = x2;
x2 = i;
}
s23 = compute_slope(x2,y2,x3,y3);
s13 = compute_slope(x1,y1,x3,y3);
tpoly(x1,x2,s13,s23,y1,y3,NO_HOLD);
}
else if(y2==y3) /* case = 1 (flat bottom)*/
{
if(x3<x2)
{
i = x2; /* sort bottom sides */
x2 = x3;
x3 = i;
}
s12 = compute_slope(x1,y1,x2,y2);
s13 = compute_slope(x1,y1,x3,y3);
tpoly(x1,x1,s12,s13,y1,y3,NO_HOLD);
}
else
{
s12 = compute_slope(x1,y1,x2,y2);
s23 = compute_slope(x2,y2,x3,y3);
s13 = compute_slope(x1,y1,x3,y3);
if(s12>s13) /* case = 4 (3rd point on right) */
{
tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
tpoly(0x8000,x2,s13,s23,y2,y3,NO_HOLD);
}
else /* case = 3 (3rd point on left) */
{
tpoly(x1,x1,s12,s13,y1,y2,R_HOLD);
tpoly(x2,0x8000,s23,s13,y2,y3,NO_HOLD);
}
}
}
/******************* 4-SIDED CONVEX POLY DRAW AND FILL **************/
/* draw quad poly-- MUST BE CONVEX */
/* will draw some concave polys OK */
/* but can't be depended on esp. */
/* if concavity is at top or bot. */
poly4(int x1, int y1, int x2, int y2, int x3, int y3,
int x4, int y4, int color)
{
register int i;
long s12, s13, s24, s14, s23 ,s34;
/* find if all outside of window */
/* sort of braindead partial clipping */
/* but it's fast and optimal for */
/* small polys */
i = r_clip;
if(!( x1<=i || x2<=i || x3<=i || x4<=i )) return(0);
i = l_clip;
if(!( x1>=i || x2>=i || x3>=i || x4>=i )) return(0);
i = b_clip;
if(!( y1<=i || y2<=i || y3<=i || y4<=i )) return(0);
i = t_clip;
if(!( y1>=i || y2>=i || y3>=i || y4>=i )) return(0);
if(y2<y1) /* sort by vert pos'n */
{ /* an unrolled bubble sort */
i = y1; /* early termination not worth it */
y1 = y2;
y2 = i;
i = x1;
x1 = x2;
x2 = i;
}
if(y3<y1)
{
i = y1;
y1 = y3;
y3 = i;
i = x1;
x1 = x3;
x3 = i;
}
if(y4<y1)
{
i = y1;
y1 = y4;
y4 = i;
i = x1;
x1 = x4;
x4 = i;
}
if(y3<y2)
{
i = y2;
y2 = y3;
y3 = i;
i = x2;
x2 = x3;
x3 = i;
}
if(y4<y2)
{
i = y2;
y2 = y4;
y4 = i;
i = x2;
x2 = x4;
x4 = i;
}
if(y4<y3)
{
i = y3;
y3 = y4;
y4 = i;
i = x3;
x3 = x4;
x4 = i;
}
load_color(color); /* set VGA color register */
if(y1==y2) goto case_a;
if(y2==y3) goto case_b;
if(y3==y4) goto case_c;
if(y4==y1) return(0); /* invisible h. line poly: exit */
goto case_d;
case_a: /* flat top */
if(y2!=y3) goto case_e;
if(y3==y4) return(0); /* invisible line */
if(x2<x1) /* sort x1 lowest, x3 highest */
{
i = x1;
x1 = x2;
x2 = i;
i = y1;
y1 = y2;
y2 = i;
}
if(x3<x2)
{
x3 = x2;
y3 = x2;
}
s14 = compute_slope(x1,y1,x4,y4); /* combine into flat-top tri */
s34 = compute_slope(x3,y3,x4,y4);
tpoly(x1,x3,s14,s34,y1,y4,NO_HOLD);
return(0);
case_e: /* flat top and bottom */
if(y3!=y4) goto case_f;
if(x2<x1) /* sort x1 lowest, x2 highest */
{
i = x1;
x1 = x2;
x2 = i;
i = y1;
y1 = y2;
y2 = i;
}
if(x4<x3) /* sort x3 lowest, x4 highest */
{
i = x3;
x3 = x4;
x4 = i;
i = y3;
y3 = y4;
y4 = i;
}
s13 = compute_slope(x1,y1,x3,y3); /* combine into parallelogram */
s24 = compute_slope(x2,y2,x4,y4);
tpoly(x1,x2,s13,s24,y1,y4,NO_HOLD);
return(0);
case_f: /* flat-top only */
if(x2<x1) /* sort x1 lowest, x2 highest */
{
i = x1;
x1 = x2;
x2 = i;
i = y1;
y1 = y2;
y2 = i;
}
if(x4<x3) /* left below right bottom */
{
s14 = compute_slope(x1,y1,x4,y4);
s23 = compute_slope(x2,y2,x3,y3);
tpoly(x1,x2,s14,s23,y1,y3,L_HOLD);
s34 = compute_slope(x3,y3,x4,y4);
tpoly(HOLD,x3,s14,s34,y3,y4,NO_HOLD);
}
else /* right below left bottom */
{
s13 = compute_slope(x1,y1,x3,y3);
s24 = compute_slope(x2,y2,x4,y4);
tpoly(x1,x2,s13,s24,y1,y3,R_HOLD);
s34 = compute_slope(x3,y3,x4,y4);
tpoly(x3,HOLD,s34,s24,y3,y4,NO_HOLD);
}
return(0);
case_b: /* sides equal height */
if(y3!=y4) goto case_g; /* not triangular? */
if(x3<x2) /* sort x2 lowest, x4 highest */
{
i = x1;
x2 = x3;
x3 = i;
i = y2;
y2 = y3;
y3 = i;
}
if(x4<x3)
{
x4 = x3;
y4 = x3;
}
s12 = compute_slope(x1,y1,x2,y2); /* combine into flat-bottom tri */
s14 = compute_slope(x1,y1,x4,y4);
tpoly(x1,x1,s12,s14,y1,y4,NO_HOLD);
return(0);
case_g: /* diamond */
if(x3<x2) /* sort x2 lowest, x3 highest */
{
i = x1;
x2 = x3;
x3 = i;
i = y2;
y2 = y3;
y3 = i;
}
s12 = compute_slope(x1,y1,x2,y2); /* draw upper, lower diamond */
s13 = compute_slope(x1,y1,x3,y3);
tpoly(x1,x1,s12,s13,y1,y2,NO_HOLD);
s24 = compute_slope(x2,y2,x4,y4);
s34 = compute_slope(x3,y3,x4,y4);
tpoly(x2,x3,s24,s34,y2,y4,NO_HOLD);
return(0);
case_c:
/* flat-bottom only */
if(x4<x3) /* sort x3 lowest, x4 highest */
{
i = x3;
x3 = x4;
x4 = i;
i = y3;
y3 = y4;
y4 = i;
}
if(x1<x2) /* left above right top */
{
s12 = compute_slope(x1,y1,x2,y2);
s13 = compute_slope(x1,y1,x3,y3);
tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
s24 = compute_slope(x2,y2,x4,y4);
tpoly(HOLD,x2,s13,s24,y2,y4,NO_HOLD);
}
else /* right above left top */
{
s12 = compute_slope(x1,y1,x2,y2);
s14 = compute_slope(x1,y1,x4,y4);
tpoly(x1,x1,s12,s14,y1,y2,R_HOLD);
s23 = compute_slope(x2,y2,x3,y3);
tpoly(x2,HOLD,s23,s14,y2,y3,NO_HOLD);
}
return(0);
case_d: /* no regularities */
s12 = compute_slope(x1,y1,x2,y2);
s13 = compute_slope(x1,y1,x3,y3);
s34 = compute_slope(x3,y3,x4,y4);
s14 = compute_slope(x1,y1,x4,y4);
if(s12<s13) /* p2 at left */
{
if(s14>s34) /* p2,p3 on opposite sides */
{
s24 = compute_slope(x2,y2,x4,y4);
tpoly(x1,x1,s12,s13,y1,y2,R_HOLD);
tpoly(x2,HOLD,s24,s13,y2,y3,L_HOLD);
tpoly(HOLD,x3,s24,s34,y3,y4,NO_HOLD);
}
else
{
s23 = compute_slope(x2,y2,x3,y3);
tpoly(x1,x1,s12,s14,y1,y2,R_HOLD);
tpoly(x2,HOLD,s23,s14,y2,y3,R_HOLD);
tpoly(x3,HOLD,s34,s14,y3,y4,NO_HOLD);
}
}
else
{
if(s14<s34) /* p2,p3 on opposite sides */
{
tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
s24 = compute_slope(x2,y2,x4,y4);
tpoly(HOLD,x2,s13,s24,y2,y3,R_HOLD);
tpoly(x3,HOLD,s34,s24,y3,y4,NO_HOLD);
}
else
{
s23 = compute_slope(x2,y2,x3,y3);
tpoly(x1,x1,s14,s12,y1,y2,L_HOLD);
tpoly(HOLD,x2,s14,s23,y2,y3,L_HOLD);
tpoly(HOLD,x3,s14,s34,y3,y4,NO_HOLD);
}
}
return(0);
}